﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;

namespace GoogleFinance
{
    /// <summary>
    /// Builds a URL query string
    /// </summary>
    public class UrlBuilder
    {
        private string _authority;
        private string _host;
        private int? _port;
        private List<KeyValuePair<string, object>> _query = new List<KeyValuePair<string, object>>();
        
        /// <summary>
        /// Constructs a instance of the class for the specified host name
        /// </summary>
        /// <param name="host">The hostname the URL is being built for</param>
        public UrlBuilder(string host)
            : this("http", host, null)
        {

        }

        /// <summary>
        /// Constructs a instance of the class for the specified authority and host name
        /// </summary>
        /// <param name="authority">The authority (e.g. http) without trailing colon and slashes</param>
        /// <param name="host">The hostname the URL is being built for</param>
        public UrlBuilder(string authority, string host)
            : this(authority, host, null)
        {
        }

        /// <summary>
        /// Constructs a instance of the class for the specified authority, hostname and port number
        /// </summary>
        /// <param name="authority">The authority (e.g. http) without trailing colon and slashes</param>
        /// <param name="host">The hostname the URL is being built for</param>
        /// <param name="port">The port number for the URL</param>
        public UrlBuilder(string authority, string host, int? port)
        {
            this._authority = authority;
            this._host = host;
            this._port = port;
        }

        /// <summary>
        /// Add a key and value pair to the query string
        /// </summary>
        /// <param name="key">The name of the query string key</param>
        /// <param name="value">The value for the query string key</param>
        /// <returns></returns>
        public UrlBuilder AddQuery(string key, object value)
        {
            this._query.Add(new KeyValuePair<string, object>(key, value));
            return this;
        }

        /// <summary>
        /// Materialises the Url and query string
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            string url = _authority + "://" + _host;
            if (_port.HasValue)
            {
                url += ":" + _port.ToString();
            }
            return AppendQuery(url);
        }

        private string AppendQuery(string url)
        {
            if (_query.Count == 0)
            {
                return url;
            }
            url += "?";
            bool isNotFirst = false;
            for (int i = 0; i < _query.Count; i++)
            {
                if (isNotFirst)
                {
                    url += "&";
                }
                url += HttpUtility.UrlEncode(_query[i].Key) 
                    + "=" 
                    + HttpUtility.UrlEncode(this._query[i].Value.ToString());
                isNotFirst = true;
            }
            return url;
        }
    }
}
